const ProfileService = require('./ProfileService');

/**
 * EntityResolutionService
 * 负责从原始数据中提取实体，并利用 ProfileService 进行身份合并
 */
class EntityResolutionService {

    /**
     * 从个人信息表提取实体
     * @param {Object} knex Transaction or Connection
     */
    static async extractFromPersonalInfo(knex) {
        const hasTable = await knex.schema.hasTable('personal_info');
        if (!hasTable) {
            console.log(`[EntityResolution] Table personal_info does not exist`);
            return 0;
        }

        const personalInfos = await knex('personal_info').select('*');
        console.log(`[EntityResolution] Found ${personalInfos.length} records in personal_info`);

        let count = 0;
        for (const info of personalInfos) {
            await ProfileService.createOrUpdateProfile(knex, {
                entity_type: 'person',
                id_card: info.id_card,
                name: info.name,
                gender: info.gender,
                birth_date: info.birth_date,
                province: info.province || info.native_place,
                phones: info.phone ? [info.phone] : [],
                addresses: info.address ? [info.address] : [],
                extra_data: info.extra_data ? JSON.parse(info.extra_data) : {},
                source_table: 'personal_info',
                source_id: info.id
            });
            count++;
        }

        console.log(`[EntityResolution] Processed ${count} personal_info records`);
        return count;
    }

    /**
     * 从银行流水提取实体 (开户人 & 对手方)
     * @param {Object} knex Transaction or Connection
     */
    static async extractFromBankTransactions(knex) {
        const hasTable = await knex.schema.hasTable('bank_transactions');
        if (!hasTable) {
            console.log(`[EntityResolution] Table bank_transactions does not exist`);
            return 0;
        }

        let count = 0;

        // 1. 提取本方账户持有者
        const bankAccounts = await knex('bank_transactions')
            .select('card_number', 'customer_name', 'id')
            .distinct('card_number'); // distinct by card_number mainly

        for (const acc of bankAccounts) {
            // 需要有卡号或身份证号才提取
            if (!acc.card_number && !acc.id_card) continue;

            await ProfileService.createOrUpdateProfile(knex, {
                entity_type: 'person',
                name: acc.customer_name,
                id_card: acc.id_card,
                accounts: acc.card_number ? [acc.card_number] : [],
                source_table: 'bank_transactions',
                // 这里如果不传source_id，可能会导致linkToProfile失败吗？
                // createOrUpdateProfile 内部不调用 linkToProfile，需要外面调
                // 但为了保持逻辑一致，我们只在ProfileService里做Create/Update
            });

            // 注意：因为这里是聚合后的 distinct 数据，无法直接拿到单条 source_id 进行 link
            // 如果需要 link 每一条交易记录，成本太高。
            // 通常 link 是指 "这个档案 拥有 这个账号"。
            // 暂时 ProfileService.createOrUpdateProfile 内部仅仅是维护 profile_entities 表
            // 具体的 link 关系 (profile_data_links) 需要额外维护，
            // 但目前的 ProfileService.extractFromBankTransactions 实现里是遍历所有 rows 做 extract + link
            // 这里的实现是 distinct 后的，为了性能。
            // 
            // 让我们看看原来的 ProfileEngine 逻辑：
            // "Use ProfileService to ensure consistency" -> createOrUpdateProfile
            // 原逻辑没有做 linkToProfile。
            // 
            // 让我们看看 ProfileService.extractFromBankTransactions (被废弃的那个)
            // 它遍历所有 rows，并且做了 linkToProfile。
            // 
            // 决策：为了性能，我们先维持 ProfileEngine 的逻辑（只提取实体），不做逐行关联。
            count++;
        }

        // 2. 提取对手方 (可选，可能会产生大量垃圾数据，方案中提到要提取)
        // 暂时只提取本方，避免对手方污染画像库，除非有明确的对手方身份信息

        console.log(`[EntityResolution] Processed ${count} distinct bank accounts`);
        return count;
    }

    /**
     * 从通话记录提取实体 
     * @param {Object} knex 
     */
    static async extractFromCallRecords(knex) {
        const hasTable = await knex.schema.hasTable('call_records');
        if (!hasTable) return 0;

        let count = 0;
        // 提取本机机主
        const owners = await knex('call_records')
            .select('phone_number', 'owner_name')
            .distinct('phone_number');

        for (const owner of owners) {
            if (!owner.phone_number) continue;

            await ProfileService.createOrUpdateProfile(knex, {
                entity_type: 'person',
                name: owner.owner_name, // 可能为空
                phones: [owner.phone_number],
                source_table: 'call_records'
            });
            count++;
        }

        console.log(`[EntityResolution] Processed ${count} call owners`);
        return count;
    }
}

module.exports = EntityResolutionService;
